import com.bazaarvoice.jolt.Chainr;
import com.bazaarvoice.jolt.JsonUtils;
import com.fasterxml.jackson.core.type.TypeReference;
import com.sl.core.domain.dto.JsonMappingFieldDefine;
import com.sl.core.engine.transfer.JoltSpecGenerator;
import com.sl.core.utils.JsonUtil;
import org.junit.jupiter.api.Test;

import java.util.*;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class JoltSpecGeneratorTest {

    private JoltSpecGenerator joltSpecGenerator = new JoltSpecGenerator();

    @Test
    public void test (){
        String mappjson = "[ {\n" +
                "  \"fieldCode\" : \"a\",\n" +
                "  \"fieldName\" : \"a\",\n" +
                "  \"fieldType\" : \"String\",\n" +
                "  \"fieldDesc\" : \"\",\n" +
                "  \"isArrayFlag\" : false,\n" +
                "  \"remark\" : \"\",\n" +
                "  \"sort\" : 0,\n" +
                "  \"path\" : \"$.a\",\n" +
                "  \"defaultValue\" : \"\",\n" +
                "  \"children\" : null,\n" +
                "  \"mappingPath\" : \"$.a\",\n" +
                "  \"mappingJsonPath\" : \"$.a\",\n" +
                "  \"jsonPath\" : \"$.a\",\n" +
                "  \"function\" : null,\n" +
                "  \"parent\" : null,\n" +
                "  \"array\" : false\n" +
                "}, {\n" +
                "  \"fieldCode\" : \"b\",\n" +
                "  \"fieldName\" : \"b\",\n" +
                "  \"fieldType\" : \"String\",\n" +
                "  \"fieldDesc\" : \"\",\n" +
                "  \"isArrayFlag\" : false,\n" +
                "  \"remark\" : \"\",\n" +
                "  \"sort\" : 0,\n" +
                "  \"path\" : \"$.b\",\n" +
                "  \"defaultValue\" : \"\",\n" +
                "  \"children\" : null,\n" +
                "  \"mappingPath\" : \"$.b\",\n" +
                "  \"mappingJsonPath\" : \"$.b\",\n" +
                "  \"jsonPath\" : \"$.b\",\n" +
                "  \"function\" : null,\n" +
                "  \"parent\" : null,\n" +
                "  \"array\" : false\n" +
                "}, {\n" +
                "  \"fieldCode\" : \"o\",\n" +
                "  \"fieldName\" : \"o\",\n" +
                "  \"fieldType\" : \"Object\",\n" +
                "  \"fieldDesc\" : \"\",\n" +
                "  \"isArrayFlag\" : false,\n" +
                "  \"remark\" : \"\",\n" +
                "  \"sort\" : 0,\n" +
                "  \"path\" : \"$.o\",\n" +
                "  \"defaultValue\" : \"\",\n" +
                "  \"children\" : [ {\n" +
                "    \"fieldCode\" : \"o1\",\n" +
                "    \"fieldName\" : \"o1\",\n" +
                "    \"fieldType\" : \"String\",\n" +
                "    \"fieldDesc\" : \"\",\n" +
                "    \"isArrayFlag\" : false,\n" +
                "    \"remark\" : \"\",\n" +
                "    \"sort\" : 0,\n" +
                "    \"path\" : \"$.o.o1\",\n" +
                "    \"defaultValue\" : \"\",\n" +
                "    \"children\" : null,\n" +
                "    \"mappingPath\" : \"$.o.o1\",\n" +
                "    \"mappingJsonPath\" : \"$.o.o1\",\n" +
                "    \"jsonPath\" : \"$.o.o1\",\n" +
                "    \"function\" : null,\n" +
                "    \"parent\" : null,\n" +
                "    \"array\" : false\n" +
                "  }, {\n" +
                "    \"fieldCode\" : \"o2\",\n" +
                "    \"fieldName\" : \"o2\",\n" +
                "    \"fieldType\" : \"String\",\n" +
                "    \"fieldDesc\" : \"\",\n" +
                "    \"isArrayFlag\" : false,\n" +
                "    \"remark\" : \"\",\n" +
                "    \"sort\" : 0,\n" +
                "    \"path\" : \"$.o.o2\",\n" +
                "    \"defaultValue\" : \"\",\n" +
                "    \"children\" : null,\n" +
                "    \"mappingPath\" : \"$.o.o2\",\n" +
                "    \"mappingJsonPath\" : \"$.o.o2\",\n" +
                "    \"jsonPath\" : \"$.o.o2\",\n" +
                "    \"function\" : null,\n" +
                "    \"parent\" : null,\n" +
                "    \"array\" : false\n" +
                "  } ],\n" +
                "  \"mappingPath\" : \"$.o\",\n" +
                "  \"mappingJsonPath\" : \"$.o\",\n" +
                "  \"jsonPath\" : \"$.o\",\n" +
                "  \"function\" : null,\n" +
                "  \"parent\" : null,\n" +
                "  \"array\" : false\n" +
                "}, {\n" +
                "  \"fieldCode\" : \"ca\",\n" +
                "  \"fieldName\" : \"ca\",\n" +
                "  \"fieldType\" : \"Object\",\n" +
                "  \"fieldDesc\" : \"\",\n" +
                "  \"isArrayFlag\" : true,\n" +
                "  \"remark\" : \"\",\n" +
                "  \"sort\" : 0,\n" +
                "  \"path\" : \"$.ca\",\n" +
                "  \"defaultValue\" : \"\",\n" +
                "  \"children\" : [ {\n" +
                "    \"fieldCode\" : \"ca1\",\n" +
                "    \"fieldName\" : \"ca1\",\n" +
                "    \"fieldType\" : \"String\",\n" +
                "    \"fieldDesc\" : \"\",\n" +
                "    \"isArrayFlag\" : false,\n" +
                "    \"remark\" : \"\",\n" +
                "    \"sort\" : 0,\n" +
                "    \"path\" : \"$.ca.ca1\",\n" +
                "    \"defaultValue\" : \"\",\n" +
                "    \"children\" : null,\n" +
                "    \"mappingPath\" : \"$.ca.ca1\",\n" +
                "    \"mappingJsonPath\" : \"$.ca[*].ca1\",\n" +
                "    \"jsonPath\" : \"$.ca[*].ca1\",\n" +
                "    \"function\" : null,\n" +
                "    \"parent\" : null,\n" +
                "    \"array\" : false\n" +
                "  }, {\n" +
                "    \"fieldCode\" : \"ca2\",\n" +
                "    \"fieldName\" : \"ca2\",\n" +
                "    \"fieldType\" : \"String\",\n" +
                "    \"fieldDesc\" : \"\",\n" +
                "    \"isArrayFlag\" : false,\n" +
                "    \"remark\" : \"\",\n" +
                "    \"sort\" : 0,\n" +
                "    \"path\" : \"$.ca.ca2\",\n" +
                "    \"defaultValue\" : \"\",\n" +
                "    \"children\" : null,\n" +
                "    \"mappingPath\" : \"$.ca.ca2\",\n" +
                "    \"mappingJsonPath\" : \"$.ca[*].ca2\",\n" +
                "    \"jsonPath\" : \"$.ca[*].ca2\",\n" +
                "    \"function\" : null,\n" +
                "    \"parent\" : null,\n" +
                "    \"array\" : false\n" +
                "  }, {\n" +
                "    \"fieldCode\" : \"ca3\",\n" +
                "    \"fieldName\" : \"ca3\",\n" +
                "    \"fieldType\" : \"Object\",\n" +
                "    \"fieldDesc\" : \"\",\n" +
                "    \"isArrayFlag\" : true,\n" +
                "    \"remark\" : \"\",\n" +
                "    \"sort\" : 0,\n" +
                "    \"path\" : \"$.ca.ca3\",\n" +
                "    \"defaultValue\" : \"\",\n" +
                "    \"children\" : [ {\n" +
                "      \"fieldCode\" : \"ca31\",\n" +
                "      \"fieldName\" : \"ca31\",\n" +
                "      \"fieldType\" : \"String\",\n" +
                "      \"fieldDesc\" : \"\",\n" +
                "      \"isArrayFlag\" : false,\n" +
                "      \"remark\" : \"\",\n" +
                "      \"sort\" : 0,\n" +
                "      \"path\" : \"$.ca.ca3.ca31\",\n" +
                "      \"defaultValue\" : \"\",\n" +
                "      \"children\" : null,\n" +
                "      \"mappingPath\" : \"$.ca.ca3.ca31\",\n" +
                "      \"mappingJsonPath\" : \"$.ca[*].ca3[*].ca31\",\n" +
                "      \"jsonPath\" : \"$.ca[*].ca3[*].ca31\",\n" +
                "      \"function\" : null,\n" +
                "      \"parent\" : null,\n" +
                "      \"array\" : false\n" +
                "    }, {\n" +
                "      \"fieldCode\" : \"ca32\",\n" +
                "      \"fieldName\" : \"ca32\",\n" +
                "      \"fieldType\" : \"String\",\n" +
                "      \"fieldDesc\" : \"\",\n" +
                "      \"isArrayFlag\" : false,\n" +
                "      \"remark\" : \"\",\n" +
                "      \"sort\" : 0,\n" +
                "      \"path\" : \"$.ca.ca3.ca32\",\n" +
                "      \"defaultValue\" : \"\",\n" +
                "      \"children\" : null,\n" +
                "      \"mappingPath\" : \"$.ca.ca3.ca32\",\n" +
                "      \"mappingJsonPath\" : \"$.ca[*].ca3[*].ca32\",\n" +
                "      \"jsonPath\" : \"$.ca[*].ca3[*].ca32\",\n" +
                "      \"function\" : null,\n" +
                "      \"parent\" : null,\n" +
                "      \"array\" : false\n" +
                "    } ],\n" +
                "    \"mappingPath\" : \"$.ca.ca3\",\n" +
                "    \"mappingJsonPath\" : \"$.ca[*].ca3[*]\",\n" +
                "    \"jsonPath\" : \"$.ca[*].ca3[*]\",\n" +
                "    \"function\" : null,\n" +
                "    \"parent\" : null,\n" +
                "    \"array\" : true\n" +
                "  } ],\n" +
                "  \"mappingPath\" : \"$.ca\",\n" +
                "  \"mappingJsonPath\" : \"$.ca[*]\",\n" +
                "  \"jsonPath\" : \"$.ca[*]\",\n" +
                "  \"function\" : null,\n" +
                "  \"parent\" : null,\n" +
                "  \"array\" : true\n" +
                "}, {\n" +
                "  \"fieldCode\" : \"c\",\n" +
                "  \"fieldName\" : \"\",\n" +
                "  \"fieldType\" : \"\",\n" +
                "  \"fieldDesc\" : \"\",\n" +
                "  \"isArrayFlag\" : true,\n" +
                "  \"remark\" : null,\n" +
                "  \"sort\" : 0,\n" +
                "  \"path\" : \"$.c\",\n" +
                "  \"defaultValue\" : \"\",\n" +
                "  \"children\" : null,\n" +
                "  \"mappingPath\" : \"$.c\",\n" +
                "  \"mappingJsonPath\" : \"$.c[*]\",\n" +
                "  \"jsonPath\" : \"$.c[*]\",\n" +
                "  \"function\" : null,\n" +
                "  \"parent\" : null,\n" +
                "  \"array\" : true\n" +
                "} ]";
        List<JsonMappingFieldDefine> jsonMappingFieldDefine = JsonUtil.toBean(mappjson, new TypeReference<List<JsonMappingFieldDefine>>() {
        });

        String transfer = JoltSpecGenerator.transfer(jsonMappingFieldDefine);
        String jsonObj = "{\n" +
                "  \"a\": \"1\",\n" +
                "  \"b\": \"2\",\n" +
                "  \"o\": {\n" +
                "    \"o1\": \"3\",\n" +
                "    \"o2\": \"4\"\n" +
                "  },\n" +
                "  \"ca\": [\n" +
                "    {\n" +
                "      \"ca1\": \"5\",\n" +
                "      \"ca2\": \"6\",\n" +
                "      \"ca3\": [\n" +
                "        {\n" +
                "          \"ca31\": \"7\",\n" +
                "          \"ca32\": \"8\"\n" +
                "        }\n" +
                "      ],\n" +
                "      \"c\": [\n" +
                "        \"1\",\n" +
                "        \"2\"\n" +
                "      ]\n" +
                "    }\n" +
                "  ]\n" +
                "}";
        List chainrSpecJSON = JsonUtil.toList(transfer, Map.class);
        Chainr chainr = Chainr.fromSpec(chainrSpecJSON);

        Object transformedOutput = chainr.transform(JsonUtil.toMap(jsonObj));
        System.out.println(transfer);
        System.out.println(transformedOutput);
    }
    @Test
    public void testGenerateJoltSpecForSimpleObject() {
        // 构建测试数据
        JsonMappingFieldDefine idField = new JsonMappingFieldDefine();
        idField.setFieldCode("id");
        idField.setFieldName("ID");
        idField.setFieldType("String");
        idField.setMappingJsonPath("sourceId");

        JsonMappingFieldDefine nameField = new JsonMappingFieldDefine();
        nameField.setFieldCode("name");
        nameField.setFieldName("姓名");
        nameField.setFieldType("String");
        nameField.setMappingJsonPath("sourceName");
        nameField.setDefaultValue("未知");

        List<JsonMappingFieldDefine> rootFields = Arrays.asList(idField, nameField);

        // 生成Jolt规范
        List<Map<String, Object>>  joltSpec = joltSpecGenerator.generateJoltSpec(rootFields);

        // 输入JSON
        String inputJson = "{\n" +
                "  \"sourceId\": \"123\",\n" +
                "  \"sourceName\": \"张三\"\n" +
                "}";

        // 执行转换
        String outputJson = executeJoltTransformation(joltSpec.get(0), inputJson);

        // 预期输出
        String expectedOutput = "{\n" +
                "  \"id\" : \"123\",\n" +
                "  \"name\" : \"张三\"\n" +
                "}";

        // 验证结果
        assertEquals(normalizeJson(expectedOutput), normalizeJson(outputJson));
    }

    @Test
    public void testGenerateJoltSpecForNestedObject() {
        // 构建嵌套对象测试数据
        // 示例：嵌套对象映射（非数组）
        JsonMappingFieldDefine addressField = new JsonMappingFieldDefine();
        addressField.setFieldCode("address");
        addressField.setMappingJsonPath("sourceAddress");

        JsonMappingFieldDefine streetField = new JsonMappingFieldDefine();
        streetField.setFieldCode("street");
        streetField.setMappingJsonPath("street");

        addressField.setChildren(Arrays.asList(streetField));

        List<JsonMappingFieldDefine> rootFields = Arrays.asList(addressField);
        System.out.println("输入的映射关系" + JsonUtil.toStr(rootFields));

        // 生成Jolt规范
        List<Map<String, Object>>  joltSpec = joltSpecGenerator.generateJoltSpec(rootFields);

        // 输入JSON
        String inputJson = "{\n" +
                "  \"operation\": \"shift\",\n" +
                "    \"sourceId\": \"id\",\n" +
                "    \"sourceAddress\": {\n" +
                "      \"street\": \"address.street\",\n" +
                "      \"city\": \"address.city\"\n" +
                "    }\n" +
                "}";
        System.out.println("输入json" + inputJson);
        System.out.println("生成的表达式是" + JsonUtil.toStr(joltSpec));

        // 执行转换
        String outputJson = executeJoltTransformation(joltSpec.get(0), inputJson);
        System.out.println("转换的返回值" + outputJson);

        // 预期输出
        String expectedOutput = "{\"street\":\"address.street\"}";

        // 验证结果
        assertEquals(normalizeJson(expectedOutput), normalizeJson(outputJson));
    }


    @Test
    public void testNestedArrayTransformation() throws Exception {
        // 1. 配置映射关系（三层嵌套数组）
        // 根数组：rootArray -> users（第一层数组）
        JsonMappingFieldDefine rootArrayField = new JsonMappingFieldDefine();
        rootArrayField.setFieldCode("users");
        rootArrayField.setMappingJsonPath("rootArray");
        rootArrayField.setIsArrayFlag(true); // 标记为数组

        // 用户字段：id -> userId，name -> userName
        JsonMappingFieldDefine userIdField = new JsonMappingFieldDefine();
        userIdField.setFieldCode("userId");
        userIdField.setMappingJsonPath("id");

        JsonMappingFieldDefine userNameField = new JsonMappingFieldDefine();
        userNameField.setFieldCode("userName");
        userNameField.setMappingJsonPath("name");

        // 订单数组：orders -> userOrders（第二层数组）
        JsonMappingFieldDefine ordersField = new JsonMappingFieldDefine();
        ordersField.setFieldCode("userOrders");
        ordersField.setMappingJsonPath("orders");
        ordersField.setIsArrayFlag(true); // 标记为数组

        // 订单字段：orderId -> orderNumber
        JsonMappingFieldDefine orderNumberField = new JsonMappingFieldDefine();
        orderNumberField.setFieldCode("orderNumber");
        orderNumberField.setMappingJsonPath("orderId");

        // 订单项数组：items -> orderItems（第三层数组）
        JsonMappingFieldDefine itemsField = new JsonMappingFieldDefine();
        itemsField.setFieldCode("orderItems");
        itemsField.setMappingJsonPath("items");
        itemsField.setIsArrayFlag(true); // 标记为数组

        // 订单项字段：product -> itemName，quantity -> itemCount
        JsonMappingFieldDefine itemNameField = new JsonMappingFieldDefine();
        itemNameField.setFieldCode("itemName");
        itemNameField.setMappingJsonPath("product");

        JsonMappingFieldDefine itemCountField = new JsonMappingFieldDefine();
        itemCountField.setFieldCode("itemCount");
        itemCountField.setMappingJsonPath("quantity");

        // 层级关联（三层嵌套）
        itemsField.setChildren(Arrays.asList(itemNameField, itemCountField));
        ordersField.setChildren(Arrays.asList(orderNumberField, itemsField));
        rootArrayField.setChildren(Arrays.asList(userIdField, userNameField, ordersField));

        // 2. 生成Jolt规范
        List<JsonMappingFieldDefine> rootFields = Collections.singletonList(rootArrayField);
        List<Map<String, Object>>  joltSpec = joltSpecGenerator.generateJoltSpec(rootFields);

        // 3. 输入JSON
        String inputJson = """
                {
                  "rootArray": [
                    {
                      "id": "1",
                      "name": "张三",
                      "orders": [
                        {
                          "orderId": "ORD-1001",
                          "items": [
                            { "product": "苹果", "quantity": 2 },
                            { "product": "香蕉", "quantity": 3 }
                          ]
                        }
                      ]
                    }
                  ]
                }
                """;

        // 4. 执行Jolt转换（此处需补充实际转换逻辑，示例省略具体实现）
        String outputJson = executeJoltTransformation(joltSpec.get(0), inputJson);

        // 5. 断言验证
        String expectedJson = """
                {
                  "users": [
                    {
                      "userId": "1",
                      "userName": "张三",
                      "userOrders": [
                        {
                          "orderNumber": "ORD-1001",
                          "orderItems": [
                            { "itemName": "苹果", "itemCount": 2 },
                            { "itemName": "香蕉", "itemCount": 3 }
                          ]
                        }
                      ]
                    }
                  ]
                }
                """;

        assert outputJson.equals(expectedJson);
    }

    @Test
    public void testComplexJoltTransformation() throws Exception {
        // 配置映射关系（模拟生成上述Jolt规范的配置）
        // 根字段：rating
        JsonMappingFieldDefine ratingField = new JsonMappingFieldDefine();
        ratingField.setFieldCode("rating");
        ratingField.setMappingJsonPath("rating");

        // primary子字段
        JsonMappingFieldDefine primaryField = new JsonMappingFieldDefine();
        primaryField.setFieldCode("primary");
        primaryField.setMappingJsonPath("primary");

        JsonMappingFieldDefine valueField = new JsonMappingFieldDefine();
        valueField.setFieldCode("Rating");
        valueField.setMappingJsonPath("value");

        JsonMappingFieldDefine maxField = new JsonMappingFieldDefine();
        maxField.setFieldCode("RatingRange");
        maxField.setMappingJsonPath("max");

        primaryField.setChildren(Arrays.asList(valueField, maxField));

        // 通配符子字段
        JsonMappingFieldDefine wildcardField = new JsonMappingFieldDefine();
        wildcardField.setFieldCode("*");
        wildcardField.setMappingJsonPath("*");

        JsonMappingFieldDefine secondaryRangeField = new JsonMappingFieldDefine();
        secondaryRangeField.setFieldCode("SecondaryRatings.&1.Range");
        secondaryRangeField.setMappingJsonPath("max");

        JsonMappingFieldDefine secondaryValueField = new JsonMappingFieldDefine();
        secondaryValueField.setFieldCode("SecondaryRatings.&1.Value");
        secondaryValueField.setMappingJsonPath("value");

        JsonMappingFieldDefine secondaryIdField = new JsonMappingFieldDefine();
        secondaryIdField.setFieldCode("SecondaryRatings.&1.Id");
        secondaryIdField.setMappingJsonPath("$");

        wildcardField.setChildren(Arrays.asList(secondaryRangeField, secondaryValueField, secondaryIdField));

        ratingField.setChildren(Arrays.asList(primaryField, wildcardField));

        // 构建Jolt规范
        List<JsonMappingFieldDefine> rootFields = new ArrayList<>();
        rootFields.add(ratingField);
        List<Map<String, Object>>  joltSpec = joltSpecGenerator.generateJoltSpec(rootFields);

        // 输入JSON
        String inputJson = "{" +
                "  \"rating\": {" +
                "    \"primary\": {" +
                "      \"value\": 4," +
                "      \"max\": 5" +
                "    }," +
                "    \"quality\": {" +
                "      \"value\": 3.5," +
                "      \"max\": 4" +
                "    }" +
                "  }" +
                "}";

        // 执行Jolt转换（此处假设JoltSpecGenerator有执行转换的方法executeJoltTransformation）
        String outputJson = executeJoltTransformation(joltSpec.get(0), inputJson);

        // 预期输出JSON
        String expectedJson = "{" +
                "  \"Rating\": 4," +
                "  \"RatingRange\": 5," +
                "  \"SecondaryRatings\": {" +
                "    \"quality\": {" +
                "      \"Range\": 5," +
                "      \"Value\": 3.5," +
                "      \"Id\": \"quality\"" +
                "    }" +
                "  }" +
                "}";

        assertEquals(expectedJson, outputJson);
    }

    @Test
    public void testGenerateJoltSpecForArray() {
        // 构建数组测试数据
        // 根字段：users数组，映射到sourceUsers数组
        JsonMappingFieldDefine usersField = new JsonMappingFieldDefine();
        usersField.setFieldCode("users");
        usersField.setMappingJsonPath("sourceUsers");
        usersField.setIsArrayFlag(true); // 标记为数组

// 子字段：id
        JsonMappingFieldDefine idField = new JsonMappingFieldDefine();
        idField.setFieldCode("id");
        idField.setMappingJsonPath("id");

// 子字段：name
        JsonMappingFieldDefine nameField = new JsonMappingFieldDefine();
        nameField.setFieldCode("name");
        nameField.setMappingJsonPath("name");

        usersField.setChildren(Arrays.asList(idField, nameField));

        List<JsonMappingFieldDefine> rootFields = Arrays.asList(usersField);

        // 生成Jolt规范
        List<Map<String, Object>>  joltSpec = joltSpecGenerator.generateJoltSpec(rootFields);

        // 输入JSON
        String inputJson = "{\n" +
                "  \"sourceUsers\": [\n" +
                "    { \"id\": \"1\", \"name\": \"张三\" },\n" +
                "    { \"id\": \"2\", \"name\": \"李四\" }\n" +
                "  ]\n" +
                "}";

        // 执行转换
        String outputJson = executeJoltTransformation(joltSpec.get(0), inputJson);

        // 预期输出
        String expectedOutput = "{\n" +
                "  \"users\" : [ {\n" +
                "    \"id\" : \"1\",\n" +
                "    \"name\" : \"张三\"\n" +
                "  }, {\n" +
                "    \"id\" : \"2\",\n" +
                "    \"name\" : \"李四\"\n" +
                "  } ]\n" +
                "}";

        // 验证结果
        assertEquals(normalizeJson(expectedOutput), normalizeJson(outputJson));
    }

    @Test
    public void testGenerateJoltSpecWithDefaultValue() {
        // 构建测试数据 - 包含默认值
        JsonMappingFieldDefine idField = new JsonMappingFieldDefine();
        idField.setFieldCode("id");
        idField.setMappingJsonPath("sourceId");

        JsonMappingFieldDefine nameField = new JsonMappingFieldDefine();
        nameField.setFieldCode("name");
        nameField.setDefaultValue("未知");

        List<JsonMappingFieldDefine> rootFields = Arrays.asList(idField, nameField);

        // 生成Jolt规范
        List<Map<String, Object>>  joltSpec = joltSpecGenerator.generateJoltSpec(rootFields);

        // 输入JSON - 缺少name字段
        String inputJson = "{\n" +
                "  \"sourceId\": \"123\"\n" +
                "}";

        // 执行转换
        String outputJson = executeJoltTransformation(joltSpec.get(0), inputJson);

        // 预期输出 - 包含默认值
        String expectedOutput = "{\\n\" +\n" +
                "                \"  \\\"sourceId\\\": \\\"123\\\"\\n\" +\n" +
                "                \"}";

        // 验证结果
        assertEquals(normalizeJson(expectedOutput), normalizeJson(outputJson));
    }

    /**
     * 执行Jolt转换
     */
    private String executeJoltTransformation(Map<String, Object> joltSpec, String inputJson) {
        try {
            // 解析Jolt规范
            List<Object> chainrSpecJSON = Arrays.asList(joltSpec);
            Chainr chainr = Chainr.fromSpec(chainrSpecJSON);

            // 解析输入JSON
            Object input = JsonUtils.jsonToObject(inputJson);

            // 执行转换
            Object output = chainr.transform(input);

            // 转换为JSON字符串
            return JsonUtils.toJsonString(output);
        } catch (Exception e) {
            throw new RuntimeException("执行Jolt转换失败", e);
        }
    }

    /**
     * 规范化JSON字符串（移除空格和换行符）以便比较
     */
    private String normalizeJson(String json) {
        return json.replaceAll("\\s+", "").trim();
    }
}